﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BIZModel;
using System.Web.UI.HtmlControls;
using System.Collections.Specialized;

namespace BL.BetterControls
{


    [Serializable]
    public enum NavMenuType
    {
        TopBar,SubBar
    }

    [DefaultProperty("Text")]
    [ToolboxData("<{0}:_NavMenu runat=server></{0}:_NavMenu>")]
    public class _NavMenu : PlaceHolder, IPostBackEventHandler
    {
        int pNL = 0;
        SortedList<Guid, HtmlGenericControl> UlList = null;
        SortedList<Guid, HtmlGenericControl> LIList = null;

        public delegate void MenuClickHandler(Guid selectedItem);
        public event MenuClickHandler MenuClick;

        public event EventHandler MenuRootClick;

        /// <summary>
        /// Skapar 1 navigerigsmeny med rooten som första val. Namn på denna navigering är propery: RootName.
        /// Sätts denna till false (default) Blir RootName satt som hemlänk och för varje första nivå under root så skapas en ny navigerings meny. 
        /// </summary>
        public bool OnlyOneNavTree { get { return ViewState["OnlyOneNavTree"] != null ? (bool)ViewState["OnlyOneNavTree"] : false; } set { ViewState["OnlyOneNavTree"] = value; } }
        public string NavTreeIconClass { get { return ViewState["NavTreeIconClass"] != null ? (string)ViewState["NavTreeIconClass"] : ""; } set { ViewState["NavTreeIconClass"] = value; } }
        public string RootName { get { return ViewState["RootName"] != null ? (string)ViewState["RootName"] : "Start"; } set { ViewState["RootName"] = value; } }
        public string BreadCrumbParentDesc { get { return ViewState["BreadCrumbParentDesc"] != null ? (string)ViewState["BreadCrumbParentDesc"] : "Menyval ovanför"; } set { ViewState["BreadCrumbParentDesc"] = value; } }
        public string BreadCrumbChildDesc { get { return ViewState["BreadCrumbChildDesc"] != null ? (string)ViewState["BreadCrumbChildDesc"] : "Menyval under"; } set { ViewState["BreadCrumbChildDesc"] = value; } }

        private List<Navigation> data { get { return ViewState["data"] != null ? (List<Navigation>)ViewState["data"] : null; } set { ViewState["data"] = value; } }
        public Guid SelectedId { get { return ViewState["SelectedId"] != null ? (Guid)ViewState["SelectedId"] : Guid.Empty; } set { ViewState["SelectedId"] = value; } }
        public string AppendNodeIdAsQueryParameter { get { return ViewState["AppendNodeIdAsQueryParameter"] != null ? (string)ViewState["AppendNodeIdAsQueryParameter"] : ""; } set { ViewState["AppendNodeIdAsQueryParameter"] = value; } }



        //public PlaceHolder RightMenuPH { get { return ViewState["RightMenuPH"] != null ? (PlaceHolder)ViewState["RightMenuPH"] : null; } set { ViewState["RightMenuPH"] = value; } }
        public string RightMenuPHId { get { return ViewState["RightMenuPHId"] != null ? (string)ViewState["RightMenuPHId"] : ""; } set { ViewState["RightMenuPHId"] = value; } }

        public NavMenuType MenuType { get { return ViewState["MenuType"] != null ? (NavMenuType)ViewState["MenuType"] : NavMenuType.TopBar; } set { ViewState["MenuType"] = value; } }


        private PlaceHolder RightMenuPH { get; set; }



        protected override void Render(HtmlTextWriter writer)
        {


            base.Render(writer);
        }

        private void RenderEmptyMenu()
        {
            this.Controls.Clear();
        }

        public void LoadMenu(List<Navigation> navigaionData, Guid selectedId)
        {
            this.Controls.Clear();

            HtmlGenericControl navControl = new HtmlGenericControl("nav");
            
            if(MenuType == NavMenuType.TopBar)
                navControl.Attributes["class"] = "top-bar";
            else
                navControl.Attributes["class"] = "sub-bar";

            navControl.ID = this.ID + "navmenu";
            this.Controls.Add(navControl);

            HtmlGenericControl titleUL = new HtmlGenericControl("ul");
            navControl.Controls.Add(titleUL);

            HtmlGenericControl section = new HtmlGenericControl("section");
            navControl.Controls.Add(section);
            
            HtmlAnchor rootA = new HtmlAnchor();

            //Flera navmenyer och en home länk
            if(OnlyOneNavTree == false)
            {
                HtmlGenericControl homeLI = new HtmlGenericControl("li");
                HtmlGenericControl homeH2 = new HtmlGenericControl("h2");

                homeLI.Attributes["class"] = "name";
                
                if (MenuRootClick != null)
                {
                    rootA.HRef = Page.ClientScript.GetPostBackClientHyperlink(this, "ROOT");
                    rootA.Title = "Klicka för att öppna " + RootName;
                }
                else
                {
                    rootA.HRef = "javascript:void(0)";
                    rootA.Title = "";
                }

                rootA.InnerText = RootName;
                homeH2.Controls.Add(rootA);
                homeLI.Controls.Add(homeH2);
                titleUL.Controls.Add(homeLI);
            }
            //<li class="toggle-topbar"><a href="#"></a></li>
            HtmlGenericControl toggleLI = new HtmlGenericControl("li");
            HtmlAnchor toggleA = new HtmlAnchor();
            toggleLI.Attributes["class"] = "toggle-topbar";
            toggleA.HRef = "javascript:void(0)";
            toggleLI.Controls.Add(toggleA);
            titleUL.Controls.Add(toggleLI);
            

            UlList = new SortedList<Guid, HtmlGenericControl>();
            LIList = new SortedList<Guid, HtmlGenericControl>();

            data = navigaionData;
            SelectedId = selectedId;

            if (navigaionData != null && navigaionData.Count > 0)
            {
                string selectedPath = "";
                int selectedLevel = 0;

                if (selectedId != Guid.Empty)
                {
                    Navigation selectedNode = navigaionData.FirstOrDefault(q => q.NodeId == selectedId);
                    if (selectedNode != null)
                    {
                        selectedPath = selectedNode.NodePath;
                        selectedLevel = selectedNode.NodeLevel.Value;
                    }
                }


                HtmlGenericControl rootUL = new HtmlGenericControl("ul");
                rootUL = new HtmlGenericControl("ul");
                rootUL.Attributes["class"] = "left";
                section.Controls.Add(rootUL);

                HtmlGenericControl rootLI = new HtmlGenericControl("li");
                //bara en navmeny där rooten är första/översta valet (dvs navmenyn)
                if (OnlyOneNavTree)
                {
                    rootLI.Attributes["class"] = "has-dropdown";

                    if (MenuRootClick != null)
                    {
                        rootA.HRef = Page.ClientScript.GetPostBackClientHyperlink(this, "ROOT");
                        rootA.Title = "Klicka för att öppna " + RootName;
                    }
                    else
                    {
                        rootA.HRef = "javascript:void(0)";
                        rootA.Title = "";
                    }
                    rootA.InnerText = RootName;
                    rootA.Attributes["class"] = NavTreeIconClass;
                    rootLI.Controls.Add(rootA);

                    rootUL.Controls.Add(rootLI);
                }

                //Breadcrumb nav
                bool BCFirstParent = true;
                bool BCFirstChild = true;
                HtmlGenericControl BcNavLI = new HtmlGenericControl("li");
                BcNavLI.Attributes["class"] = "has-dropdown";
                
                HtmlAnchor BCA = new HtmlAnchor();
                BCA.HRef = "javascript:void(0)";
                BCA.Attributes["class"] = "foundicon-location";
                
                HtmlGenericControl BCNavUL = new HtmlGenericControl("ul");
                BCNavUL.Attributes["class"] = "dropdown";
                BcNavLI.Controls.Add(BCA);
                BcNavLI.Controls.Add(BCNavUL);

                BCA.InnerText = RootName;
                if (selectedLevel > 2)
                {
                    BCA.InnerText = RootName + @"\...";
                }

                HtmlGenericControl UL = new HtmlGenericControl("ul");
                
                int bntId = 0;

                foreach (Navigation nav in navigaionData)
                {
                    bntId ++;

                    int NL = nav.NodeLevel.HasValue ? nav.NodeLevel.Value : 0;

                    //första nivån (det ska alltid bara finnas en root)
                    if (NL == 0 && pNL == 0)
                    {

                    }
                    else if (NL > pNL) //Ny nivå under
                    {
                        //om flera navmenyer så ska nivå 1 skapa nya LI under rootUL. Om bara 1 navmeny så finns det en rootLI där allt under ska skapas.
                        if (NL == 1 && OnlyOneNavTree == false)
                        {
                            UL = rootUL;
                        }
                        else
                        {
                            //kolla om det finns en UL skapad sedan tidigare
                            if (UlList.ContainsKey(nav.NodeParentId.Value))
                            {
                                UL = UlList[nav.NodeParentId.Value];
                            }
                            else //annars skapa en ny och lägg till den under förälderns UL
                            {
                                HtmlGenericControl parentLi = LIList[nav.NodeParentId.Value];
                                parentLi.Attributes["class"] = "has-dropdown";

                                UL = new HtmlGenericControl("ul");
                                UL.Attributes["class"] = "dropdown";
                                parentLi.Controls.Add(UL);
                                UlList.Add(nav.NodeParentId.Value, UL);
                            }
                        }
                    }
                    else if (NL == pNL) //samma nivå
                    {
                        //Gör inget utan används samma ul som man har hämtat i (NL > pNL) ovan eller  (NL < pNL) nedan
                        //Man har alltid varit i någon av dessa if innan man kan komma hit 
                    }
                    else if (NL < pNL) //backar upp en/flera nivåer 
                    {
                        //Hämta den UL som gäller för denna nivå
                        if (NL == 0)
                        {
                            //DET HÄR SKA INTE HÄNDA OM MAN HÄMTAR DATAT RÄTT DÅ DET ALLTID SKA BARA VARA EN ROT MED LEVEL 0!!!!!
                            //MEN OM DET NU GÖR DET SÅ BLIR DER FLERA LI UDNER ROTEN
                            UL = rootUL;
                        }
                        else if (NL == 1 && OnlyOneNavTree == false) //om flera navmenyer så ska nivå 1 skapa nya LI under rootUL. Om bara 1 navmeny så finns det en rootLI där allt under ska skapas.
                        {
                            UL = rootUL; 
                        }
                        else
                        {
                            UL = UlList[nav.NodeParentId.Value];
                        }
                    }

                    HtmlGenericControl LI = new HtmlGenericControl("li");
                    HtmlAnchor LBA = new HtmlAnchor();

                    string href = "";
                    if (string.IsNullOrEmpty(nav.NodeNavUrl))
                    {
                        href = Page.ClientScript.GetPostBackClientHyperlink(this, nav.NodeId.ToString());
                    }
                    else
                    {

                        if (AppendNodeIdAsQueryParameter != "")
                        {
                            string QP = nav.NodeNavUrl.Contains('?') ? "&" : "?";

                            QP += AppendNodeIdAsQueryParameter + "=" + nav.NodeId.ToString();

                           href = nav.NodeNavUrl + QP;

                        }
                        else
                        {
                            href = nav.NodeNavUrl;
                        }
                           
                    }
                    //Skriver över data i root li/a med data från första menyalternativet
                    if (NL == 0 && pNL == 0)
                    {
                        LBA = rootA;                       
                        LBA.Title = "Klicka för att öppna " + RootName;
                        LBA.HRef = href;

                        //Skapar 1 rootLI om det ska finnas flera navmenyer
                        if (OnlyOneNavTree)
                        {
                            LI = rootLI;
                            LIList.Add(nav.NodeId, LI);
                        }
                    }
                    else
                    {
                        LBA.HRef = href;
                        LBA.InnerText = nav.NodeName;
                        LBA.Title = "Klicka för att öppna " + nav.NodeName;
                        LI.Controls.Add(LBA);

                        UL.Controls.Add(LI);
                        LIList.Add(nav.NodeId, LI);
                    }


                    #region breadcrumb
                    if (NL == 0 && pNL == 0)
                    {
                        //gör något i breadcrumb när man är på rooten
                        HtmlGenericControl bcLi = null;
                        //En förklarande text överst
                        if (BCFirstParent)
                        {
                            bcLi = new HtmlGenericControl("li");
                            HtmlGenericControl bcLabel = new HtmlGenericControl("label");
                            bcLabel.InnerText = BreadCrumbParentDesc;
                            bcLi.Controls.Add(bcLabel);
                            BCNavUL.Controls.Add(bcLi);
                            BCFirstParent = false;
                        }

                        bcLi = new HtmlGenericControl("li");
                        HtmlAnchor bcA = new HtmlAnchor();
                        bcA.HRef = rootA.HRef;
                        bcA.InnerText = RootName;
                        bcA.Title = "Klicka för att öppna " + RootName; 
                        bcLi.Controls.Add(bcA);
                        BCNavUL.Controls.Add(bcLi);
                    }
                    else
                    {
                        //Breadcrumb nav
                        if (nav.NodeId == selectedId)
                        {
                            //lägger till i breadcrumb texten fö
                            BCA.InnerText += @"\" + nav.NodeName;
                        }
                        else if (selectedPath.Contains(nav.NodePath)) //hir uppåt från selected
                        {
                            //Lägger till föräldrar i breadcrumb texten
                            if (selectedLevel <= 2)
                            {
                                BCA.InnerText += @"\" + nav.NodeName;
                            }
                            else if (nav.NodeLevel == selectedLevel || nav.NodeLevel == (selectedLevel - 1)) //skriv bara ut två sista nivåer om det är långt ner typ X\...\x\x
                            {
                                BCA.InnerText += @"\" + nav.NodeName;
                            }

                            //skapar menyval för alla uppåt i hierarkin
                            HtmlGenericControl bcLi = null;
                            //En förklarande text överst
                            if (BCFirstParent)
                            {
                                bcLi = new HtmlGenericControl("li");
                                HtmlGenericControl bcLabel = new HtmlGenericControl("label");
                                bcLabel.InnerText = BreadCrumbParentDesc;
                                bcLi.Controls.Add(bcLabel);
                                BCNavUL.Controls.Add(bcLi);
                                BCFirstParent = false;
                            }

                            bcLi = new HtmlGenericControl("li");
                            HtmlAnchor bcA = new HtmlAnchor();
                            bcA.HRef = href;
                            bcA.InnerText = nav.NodeName;
                            bcA.Title = "Klicka för att öppna " + nav.NodeName;
                            bcLi.Controls.Add(bcA);
                            BCNavUL.Controls.Add(bcLi);


                        }
                        else if (nav.NodeLevel == selectedLevel + 1 && nav.NodePath.Contains(selectedPath))  //barn 1 nivå ner från selected
                        {
                            //skapar menyalternativ för barnen
                            HtmlGenericControl bcLi = null;
                            //En förklarande text före första barnet
                            if (BCFirstChild)
                            {
                                bcLi = new HtmlGenericControl("li");
                                HtmlGenericControl bcLabel = new HtmlGenericControl("label");
                                bcLabel.InnerText = BreadCrumbChildDesc;
                                bcLi.Controls.Add(bcLabel);
                                BCNavUL.Controls.Add(bcLi);
                                BCFirstChild = false;
                            }

                            bcLi = new HtmlGenericControl("li");

                            HtmlAnchor bcA = new HtmlAnchor();
                            bcA.HRef = href;
                            bcA.InnerText = nav.NodeName;
                            bcA.Title = "Klicka för att öppna " + nav.NodeName;
                            bcLi.Controls.Add(bcA);
                            BCNavUL.Controls.Add(bcLi);

                        }
                    }
                    #endregion


                    pNL = NL;


                }


                rootUL.Controls.Add(BcNavLI);
                
            }

            if (RightMenuPH != null)
            {
                section.Controls.Add(RightMenuPH);
            }
        }

        protected override void AddParsedSubObject(object obj)
        {
            base.AddParsedSubObject(obj);

            if (obj is PlaceHolder)
            {
                PlaceHolder control = (PlaceHolder)obj;

                if (control.ID == RightMenuPHId)
                {
                    if (control.Visible)
                    {
                        RightMenuPH = (PlaceHolder)control;
                        base.AddParsedSubObject(RightMenuPH);
                    }
                }
            }
        }



           

        protected override void RenderChildren(HtmlTextWriter writer)
        {


            base.RenderChildren(writer);
        }

        public override void RenderControl(HtmlTextWriter writer)
        {
            base.RenderControl(writer);
        }


        protected override void OnPreRender(EventArgs e)
        {
            bool loadmenu = false;

            if(this.Controls.Count == 0)
                loadmenu = true;

            if(this.Controls.Count == 1 && this.Controls[0].ID == RightMenuPHId)
                  loadmenu = true;


            if (loadmenu && data != null)
            {
                LoadMenu(data, SelectedId);
            }
            else if (loadmenu && data == null && RightMenuPH != null)
            {
                //TODO:Undra om det blir rätt det här eller om det krockar på något sätt med när man laddar data från sidan där kontrollen är inlagd

                //RightMenuPH.Visible = false;   
                LoadMenu(data, SelectedId);
            }
           

            base.OnPreRender(e);
        }

        public void RaisePostBackEvent(string eventArgument)
        {
            if (eventArgument == "ROOT")
            {
                SelectedId = Guid.Empty;
                if (MenuRootClick != null)
                {
                    MenuRootClick(this, null);
                }

                LoadMenu(data, Guid.Empty);


            }
            else
            {
                SelectedId = Guid.Parse(eventArgument);
                
                if (MenuClick != null)
                {
                    MenuClick(SelectedId);
                }

                LoadMenu(data, SelectedId);


            }
        }


    }
}

